package rlex.classes;

import java.util.ArrayList;

public class IdentifierStack {
	ArrayList<ArrayList<Identifier>> identifiers;
	
	public IdentifierStack() {
		identifiers = new ArrayList<ArrayList<Identifier>>();
		PushNewLevel(); // Init the first level
	}
	
	/**
	 * New entry in the stack
	 */
	public void PushNewLevel() {
		ArrayList<Identifier> level = new ArrayList<Identifier>();
		identifiers.add(level);
	}
	
	/**
	 * Exit the last entry
	 */
	public void PopLevel() {
		identifiers.remove(identifiers.size() - 1);
	}
	
	public void AddIdentifier(Identifier id) throws Exception {
		Identifier exist = getIdentifierInLastLevel(id.getName());
		if (exist == null) {
			identifiers.get(identifiers.size() - 1).add(id);
		} else {
			throw new Exception("Identifier " + id.getName() + " already exist");
		}
	}
	
	public Identifier getIdentifier(String name) {
		//System.out.print("Entering in getIdentifier(" + name + ")\n");
		for (int i = (identifiers.size() - 1); i >= 0; i--) {
			Identifier type = getIdentifierInScope(name, identifiers.get(i));
			if (type != null) {
				//System.out.print("Find ! Returning " + type.getName() + ":" + type.getType() + "\n");
				return type;
			}
		}
		return null;
	}
	
	public Identifier getIdentifierInLastLevel(String name) {
		Identifier type = getIdentifierInScope(name, identifiers.get(identifiers.size() - 1));	
		return type;
	}
	
	private Identifier getIdentifierInScope(String name, ArrayList<Identifier> arr) {
		for (int i = 0; i < arr.size(); i++) {
			if (arr.get(i).getName().equals(name)) {
				return arr.get(i);
			}
		}
		return null;
	}
	
	public void display() {
		for (int i = (identifiers.size() - 1); i >= 0; i--) {
			System.out.print("Level " + i + ": ");
			for (int j = (identifiers.get(i).size() - 1); j >= 0; j--) {
				identifiers.get(i).get(j).display();
				System.out.print(",");
			}
			System.out.print("\n");
		}
	}
}
